/*
 * Copyright 2010-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.newpath.core.beanresource;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.google.code.newpath.config.BeanResourceConfig;
import com.google.code.newpath.core.Path;
import com.google.code.newpath.core.ResourceCreator;
import com.google.code.newpath.core.ResourceConfig;
import com.google.code.newpath.core.exception.ResourceException;
import com.google.code.newpath.core.exception.ResourceNotFoundException;
/**
 * 
 * @author Charlie Zhang 
 *
 */
public class BeanResourceCreator implements ResourceCreator<BeanResource> {

	public final static String DEFAULT_SUFFIX = "pb";
	
	private String suffix;
	
	private Path startPath;
	
	private String basePackage;
	
	private String defaultScope;
	
	private BeanPathConverter pathConverter;
	
	private ClassLoader classLoader;
	
	/**
	 * 
	 * @param startPath The start path will append before parse path. For instance: <br/>
	 *        If this argument is "/service", the all resource path which build from this factory will look like "/service/somepath".  
	 * @param basePackage The base java package to find bean class. This factory will find the classes under the descendants of this package. 
	 * @param defaultScope Default lifecycle scope for which bean not specific declare it.
	 * @param pathConverter A customize class to convert from resourcePath to javaBean Define
	 */
	public BeanResourceCreator(Path startPath, String basePackage, BeanPathConverter pathConverter, String suffix, String defaultScope) {
		this.startPath = startPath;
		this.basePackage = basePackage;
		this.pathConverter = pathConverter;
		this.suffix = suffix;
		this.defaultScope = defaultScope;

	}
	
	public BeanResourceCreator(Path startPath, String basePackage, BeanPathConverter pathConverter, String defaultScope) {
		this(startPath, basePackage, pathConverter, DEFAULT_SUFFIX, defaultScope);
	}
	
	public BeanResourceCreator(Path startPath, String basePackage, String defaultScope) {
		this(startPath, basePackage, new DefaultPathConverter(), DEFAULT_SUFFIX, defaultScope);
	}

	public BeanResource createResource(Path resourcePath) {
		
		//Created the new BeanResource by resourcePath
		try {
			String className = pathConverter.convert(resourcePath, startPath, basePackage);
			return new BeanResource(this, resourcePath, className);
		}
		catch(Exception e) {
			throw new ResourceNotFoundException("Failed to found resource path=" + resourcePath, e, resourcePath);
		}
	}
	
	
	public BeanResource createResource(ResourceConfig resourceConfig) throws ResourceException { 
		try {
			return new BeanResource(this, (BeanResourceConfig)resourceConfig);
		}
		catch(Exception e) {
			throw new ResourceNotFoundException("Failed to found resource path=" + resourceConfig.getPath(), 
					e, resourceConfig.getPath());
		}
	}
	

	public String getSuffix() {
		if(suffix == null) {
			return DEFAULT_SUFFIX;
		}
		else {
			return suffix;
		}
	}
	
	
	public String getDefaultScope() {
		return defaultScope;
	}

	public ClassLoader getClassLoader() {
		if(classLoader != null) {
			return classLoader;
		}
		else {
			return this.getClass().getClassLoader();
		}
	}

	public void setClassLoader(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}

	
}
